// VBConversions Note: VB project level imports
using System.Data;
using DevExpress.XtraEditors.Controls;
using System.Diagnostics;
using System.Xml.Linq;
using DevExpress.XtraEditors.Repository;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.VisualBasic;
using System.Configuration;
using System.Collections;
using DevExpress.XtraEditors;
using System.Data.Sql;
using Microsoft.SqlServer;
using System.Windows.Forms;
using System;
using DevExpress.XtraReports;
using Microsoft.SqlServer.Management.Smo;
using DevExpress;
using System.Linq;
using System.IO;
// End of VB project level imports

using System.Text;
using System.Security.Cryptography;

//	CryptographyHelper & Cryptography .NET classes
//	http://maxvergelli.wordpress.com/

//	Copyright (c) 2010 Max Vergelli

//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:

//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.

//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.


// HOW TO USE IT HOW TO USE IT HOW TO USE IT

//Dim cryptoHelper As New CryptographyHelper

//'select your favorite encoding type of the output (note that hexadecimal result is longer then base64 compression)
//cryptoHelper.EncodingType = CryptographyHelper.EncodingBaseTypes.Hex 'CryptographyHelper.EncodingBaseTypes.Base64

//Dim password As String = "my secret password to encrypt or decrypt strings"
//Dim encryptedText As String = cryptoHelper.Encrypt("plain text to encrypt...", password)
//Dim decryptedText As String = cryptoHelper.Decrypt(encryptedText, password)

//'if you want get an hash of a string try out one of the following...
//Dim MD5hash As String = cryptoHelper.GetHash("string to hash", CryptographyHelper.HashTypes.MD5)
//Dim SHA1hash As String = cryptoHelper.GetHash("string to hash", CryptographyHelper.HashTypes.SHA1)
//Dim SHA256hash As String = cryptoHelper.GetHash("string to hash", CryptographyHelper.HashTypes.SHA256)

// HOW TO USE IT HOW TO USE IT HOW TO USE IT

namespace SCIEF.SysBFW.CommonExt
{
	namespace Utils
	{
		public class Cryptography
		{
			private string strKey = null;
			private byte[] bytKey = null;
			private UnicodeEncoding textConverter = new UnicodeEncoding();
			private RijndaelManaged rijndael = new RijndaelManaged(); //"rÃ¨in-daal" <IMG class=wp-smiley alt=:) src="http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif?m=1305841840g">
			
			public Cryptography(string encryption_key = "")
			{
				if (encryption_key != "")
				{
					EncryptionKey = encryption_key;
				}
			}
			
			
			//OutstandingIssue: Pkoi Aleblanc
			~Cryptography()
			{
				if (textConverter != null)
				{
					textConverter = null;
				}
				if (rijndael != null)
				{
					rijndael = null;
				}
				strKey = null;
				bytKey = null;
			}
			
			public string EncryptionKey
			{
				get
				{
					return strKey;
				}
				set
				{
					try
					{
						//Set the key string
						strKey = value;
						//Set hash in bytes of the key string
						SHA256Managed hash256 = new SHA256Managed();
						bytKey = hash256.ComputeHash(textConverter.GetBytes(strKey));
						hash256 = null;
						if ((bytKey.Length - 1) < 0)
						{
							return;
						}
						//Set Rijndael Key and IV vector for 256 bit encryption
						byte[] MainKey = new byte[32];
						byte[] MainIV = new byte[16];
						int iDiffBlock = 5;
						rijndael.KeySize = 256; //bit
						int n = 0;
						int x = 0;
						int y = 0;
						for (n = 0; n <= (MainKey.Length - 1); n++)
						{
							MainKey[n] = bytKey[x];
							if (n > iDiffBlock & n <= (MainIV.Length - 1) + iDiffBlock)
							{
								MainIV[y] = bytKey[x];
								y++;
							}
							x++;
							if (x > (bytKey.Length - 1))
							{
								x = 0;
							}
						}
						rijndael.Key = MainKey;
						rijndael.IV = MainIV;
					}
					catch
					{
						//set a blank encryption key then we cannot encrypt/decrypt
						strKey = null;
					}
				}
			}
			
			public byte[] Encrypt(string clear_text)
			{
				byte[] enc_bytes = null;
				if (strKey != null)
				{
					//get byte array from text
					byte[] bytes = textConverter.GetBytes(clear_text);
					//encrypt data
					ICryptoTransform encryptor = rijndael.CreateEncryptor();
					MemoryStream msEncrypt = new MemoryStream();
					CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
					//write all data to the crypto stream and flush it
					csEncrypt.Write(bytes, 0, bytes.Length);
					csEncrypt.FlushFinalBlock();
					//get encrypted byte array
					enc_bytes = msEncrypt.ToArray();
					msEncrypt.Dispose();
					csEncrypt.Dispose();
				}
				return enc_bytes;
			}
			
			public string Decrypt(byte[] encrypted_text)
			{
				string dec_text = null;
				if (strKey != null)
				{
					ICryptoTransform decryptor = rijndael.CreateDecryptor();
					MemoryStream msDecrypt = new MemoryStream(encrypted_text);
					CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
					//prepare buffer
					byte[] bytes = new byte[encrypted_text.Length - 1+ 1];
					//read the data out of the crypto stream
					csDecrypt.Read(bytes, 0, bytes.Length);
					//convert the byte array back into a string
					dec_text = textConverter.GetString(bytes);
					//strip null end chars
					StripEndNull(ref dec_text);
					msDecrypt.Dispose();
					csDecrypt.Dispose();
				}
				return dec_text;
			}
			
			public string BytesToBase64(byte[] input_bytes)
			{
				string s = null;
				s = Convert.ToBase64String(input_bytes);
				return s;
			}
			
			public byte[] Base64ToBytes(string input_base64)
			{
				byte[] b = null;
				b = Convert.FromBase64String(input_base64);
				return b;
			}
			
			public string BytesToHexString(byte[] input_bytes)
			{
				string s = null;
				//Dim s As String = BitConverter.ToString(input_bytes).Replace("-", String.Empty)
				StringBuilder builder = new StringBuilder();
				for (int i = 0; i <= input_bytes.Length - 1; i++)
				{
					builder.AppendFormat("{0:x2}", input_bytes[i]);
				}
				s = builder.ToString();
				builder = null;
				return s;
			}
			
			public byte[] HexStringToBytes(string input_hex_string)
			{
				byte[] bytes = null;
				//i variable used to hold position in string
				int i = 0;
				//x variable used to hold byte array element position
				int x = 0;
				//allocate byte array based on half of string length
				bytes = new byte[(input_hex_string.Length) / 2 - 1+ 1];
				//loop through the string - 2 bytes at a time converting
				//it to decimal equivalent and store in byte array
				while (input_hex_string.Length > i + 1)
				{
					long lngDecimal = Convert.ToInt32(input_hex_string.Substring(i, 2), 16);
					bytes[x] = Convert.ToByte(lngDecimal);
					i = i + 2;
					x++;
				}
				//return the finished byte array of decimal values
				return bytes;
			}
			
			public byte[] CreateMD5Hash(string input)
			{
				byte[] hash = null;
				byte[] bytes = textConverter.GetBytes(input);
				MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
				hash = MD5.ComputeHash(bytes);
				MD5 = null;
				return hash;
			}
			
			public byte[] CreateSHA1Hash(string input)
			{
				byte[] hash = null;
				byte[] bytes = textConverter.GetBytes(input);
				SHA1CryptoServiceProvider SHA = new SHA1CryptoServiceProvider();
				hash = SHA.ComputeHash(bytes);
				SHA = null;
				return hash;
			}
			
			public byte[] CreateSHA256Hash(string input)
			{
				byte[] hash = null;
				byte[] bytes = textConverter.GetBytes(input);
				SHA256CryptoServiceProvider SHA = new SHA256CryptoServiceProvider();
				hash = SHA.ComputeHash(bytes);
				SHA = null;
				return hash;
			}
			
			public byte[] CreateSHA512Hash(string input)
			{
				byte[] hash = null;
				byte[] bytes = textConverter.GetBytes(input);
				SHA512CryptoServiceProvider SHA = new SHA512CryptoServiceProvider();
				hash = SHA.ComputeHash(bytes);
				SHA = null;
				return hash;
			}
			
			private void StripEndNull(ref string input_string)
			{
				char nullchar = Convert.ToChar(0); //&H0
				if (input_string.Length > 0 && input_string.EndsWith(nullchar.ToString()))
				{
					int n = default(int);
					for (n = input_string.Length - 1; n >= 0; n--)
					{
						if (input_string[n] != nullchar)
						{
							input_string = input_string.Substring(0, n + 1);
							break;
						}
					}
				}
				Convert.ToString(input_string);
			}
		}
	}
}
